/*
 * @Author: lujing
 * @Date: 2024-06-13 09:29:14
 * @LastEditTime: 2024-06-25 11:32:54
 * @FilePath: \workspace\fy\aiDigitalPerson\dipu-xjy-meta-digital-person\src\pages\digitalHuman\Home.tsx
 */
import {  Box, Typography,Button,TextField ,Dialog ,DialogActions ,DialogContent ,DialogContentText ,DialogTitle  } from '@mui/material';
import DigitalBg from 'assets/digital-bg.png'
import Human from 'components/digital/HumanContainer'
import ChatBox from 'components/digital/ChatContainer'
import zantingIcon from 'assets/zanting-active.png';
import pauseIcon from 'assets/pause_02.png';
import {promtStringState, isRenderingState, loadingState, voicingState, sessionState, messagesState, IMessage,openComfirmState,fullscreenState,isLoadingFinishState, sessionState_rizhi ,initWAKEUP_NTF} from 'state/chat';
import { useRecoilState, useSetRecoilState, useRecoilValue } from 'recoil';
import { useEffect } from 'react';
import { clientState } from 'state/client';
import { v4 as uuidv4 } from 'uuid';
import {digitalIframeUrl123,digitalIframeUrl124,digitalIframeUrl125} from 'api/index';
import { toast } from 'react-hot-toast';
import FullscreenIcon from '@mui/icons-material/Fullscreen';
import fullscreenIcon from 'assets/fullscreen.png'


export default function Home() {
    const queryString = window.location.search;
    const urlParams = new URLSearchParams(queryString);
    const shuziren = urlParams.get('shuziren')=='123'?digitalIframeUrl123:urlParams.get('shuziren')=='124'?digitalIframeUrl124:digitalIframeUrl125;
    const setIsRendering = useSetRecoilState(isRenderingState);
    const setLoading = useSetRecoilState(loadingState);
    const loading = useRecoilValue(loadingState)
    const setVoicing = useSetRecoilState(voicingState);
    const session = useRecoilValue(sessionState);
    const session_rizhi = useRecoilValue(sessionState_rizhi);
    const promtString = useRecoilValue(promtStringState);
    const [messages, setMessages] = useRecoilState(messagesState)
 
    let currMessageId ="";//当前正在响应的消息id;

    let [loadingFinish,setloadingFinish] = useRecoilState(isLoadingFinishState);//加载完成，确认了页面尺寸后，再加载数字人

    const handleStopRendering = () => {
        setLoading(false);
        setIsRendering(false);
        // 打断数字人讲话，等待中
        setVoicing('event_vad_end')
        // 触发数字人讲话[停止说话]
        client.setAISay('','task_stop')
        // const lastIndex = messages.findLastIndex(obj => obj.parentId === null);
        // let message: IMessage
        // 如果找到符合条件的对象，则为其添加show: true属性
        // if (lastIndex !== -1) {
        //     message = messages[lastIndex]
        //     message.stopRendering = true
        //     setMessages((oldMessages) => {
        //        return [
        //             ...oldMessages.slice(0, lastIndex),
        //             message,
        //             ...oldMessages.slice(lastIndex + 1)
        //           ]
        //     })
        // }
        // session?.socket.emit('stop');
        // session?.socket.emit('stop');

    };
    
    const client = useRecoilValue(clientState);
    // 一些临时数据
    let dealResultStr = "";//解析后的字符串集合
    // 监听是否收到声音
    useEffect(()=>{
        if (promtString) {
            // 当两次问题提问太快的时候用来区分上一次的问题和下一次的问题，
            // 这里将这个值传入，当做新的跟对象中的原数值对比，控制调用文字输出
            const num = initWAKEUP_NTF.num
            // 打断上一个问题
            handleStopRendering();
            // 展示一条问题
            setLoading(true)
                const message: IMessage = {
                    id: uuidv4(),
                    author: '访客',
                    authorIsUser: true,
                    content: promtString,
                    createdAt: new Date().toISOString()
                };
                session_rizhi.socket_rizhi.send('数字人ID:'+urlParams.get('shuziren')+' 给到数字人展示问题时间'+getCurrentDateTime() + '，内容：'+promtString); // 发送一条日志消息

                // 添加一条消息
                setMessages((m)=>[...m,message])
                getResult(promtString,num)
                setTimeout(() => {
                    
                    setIsRendering(true)
                
                },0)//原来这里是800，yyb修改为0
        }
       
    },[promtString])

    useEffect(()=>{
        // 触发数字人说开场白
        setTimeout(()=>{
            client.setAISay('你好，我是新建元的数字员工元晓宇，请使用"晓宇晓宇"唤醒我进行提问。','stream_token')
            client.setAISay('','stream_end')
        },5000)
    },[])


  function getCurrentDateTime() {
    const now = new Date();
    const year = now.getFullYear();
    const month = (now.getMonth() + 1).toString().padStart(2, '0');
    const day = now.getDate().toString().padStart(2, '0');
    const hours = now.getHours().toString().padStart(2, '0');
    const minutes = now.getMinutes().toString().padStart(2, '0');
    const seconds = now.getSeconds().toString().padStart(2, '0');
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    };
    // 更新时间用的变量
    let time=''
    async function getResult(promtString: string,num:number) {
        let now_time = getCurrentDateTime();
        // 日志
        session_rizhi.socket_rizhi.send('数字人ID:'+urlParams.get('shuziren')+' 发送问题给大模型时间：'+now_time + '，内容：'+promtString); // 发送一条日志消息
        // 发起请求之前，清空答案变量；生成一个消息
        dealResultStr = "";
         // 生成一个消息模板
         let  messageId = uuidv4();
         currMessageId = messageId;
         let  message1: IMessage = {
            id: messageId,
            author: '元晓宇',
            authorIsUser: false,
            content: '',
            createdAt: new Date().toISOString(),
         };
        time=''//这里需要清空
        // 获取答案：思考中
        setVoicing('event_vad_think')
        setTimeout(() => {
        // 上面的思考中是微观异步，使用宏观异步获取思考中的高度
        document.getElementsByClassName('overScroll')[0].style.height = document.getElementsByClassName('1111')[0].scrollHeight-20 + 'px'
        }, 0);
        let streamController = await client.getLLMData(promtString, (done, token) => {
            // console.log('一次拉去数据==='+token)
            if(done){
                client.setAISay('','stream_end')
                // stream_start：开始推送数据
                // stream_token：正在推送数据
                // stream_end：推送数据正常结束
                // task_stop：用户打断当前交互流程
                
            } else {                
                // session_rizhi.socket_rizhi.send('数字人ID:' + urlParams.get('shuziren') + ' 用于对比的currMessageId和messageId和num和initWAKEUP_NTF.num'
                //      + now_time + '，内容：' +'id_1'+currMessageId+'id_2'+messageId +'num'+num+'initWAKEUP_NTF.num'+initWAKEUP_NTF.num); // 发送一条日志消息
                
                // 这里很重要，如果已经有新的消息，之前被打断的消息就不要一直生成
                if(currMessageId != messageId){
                    // @ts-ignore
                    streamController&&streamController.close();
                    return;
                }else if(currMessageId == messageId){
                    // 回调一次就要解析一次
                    // 对比是不是同一个问题，保证下一个问题来时，上一个问题不会调用函数
                    if (num == initWAKEUP_NTF.num) {
                        dealResult(token, messageId, message1,num);
                    } else { 
                        streamController&&streamController.close();
                    }

                }
                
            }
        })
    }
    //1
    const dealResult = (token: string, messageId: string, messageTemplate: IMessage,num:number) => {
        
            let currResult = ""
            // 从字符串结果中获得对象
        let resultList = dealStr2Arr(token)
        
            // 得到正确的答案
        resultList.forEach(item => {
                // console.log(item,'item');
                
                if (item.path == '/streamed_output/-') {
                    currResult += item.value;
                }
            })
            dealResultStr += currResult

            // 每次拉取的数据，有答案内容，就要播报和展示
        if (currResult) {
            session_rizhi.socket_rizhi.send('数字人ID:' + urlParams.get('shuziren') + 'num和init_num数字对比：' + getCurrentDateTime() + '，内容：' + num+'和'+initWAKEUP_NTF.num); // 发送一条日志消息
            // 判断如果是新的答案还是旧的答案，如果是旧的答案减少接口调用
            if (num == initWAKEUP_NTF.num) {
                client.setAISay(currResult, 'stream_token', session_rizhi.socket_rizhi)
                // 触发数字人讲话：开始讲话
                setVoicing('event_vad_begin')
            }
            let now_time = getCurrentDateTime();
            // 记录答案返回的时间展示
            if (!time) { 
                time = new Date().toISOString()
                messageTemplate.createdAt = time
            }
            console.log('对话返回时间：' + now_time + '，内容：' + dealResultStr)
            session_rizhi.socket_rizhi.send('数字人ID:' + urlParams.get('shuziren') + ' 问题得到回答并展示时间：' + getCurrentDateTime() + '，内容：' + currResult); // 发送一条日志消息
              setMessages((m)=>{
                let oldLastMsg = m[m.length-1];
                    // 此消息已经存在，继续追加内容
                    if(oldLastMsg.id == messageId){
                        // console.log('追加'+dealResultStr)
                        return[...m.slice(0,m.length-1),{...oldLastMsg,content:dealResultStr}]
                    // 需要新创建消息
                    }else{
                        // 如果最后一个消息不是当前正在回答的消息，
                        // 而且当前消息用户的提问,这个时候才追加一个消息
                        if(oldLastMsg.authorIsUser){
                            // console.log('新增'+dealResultStr)
                            let tempMsg = {...messageTemplate,content:dealResultStr}
                            return [...m,tempMsg]

                        }else{
                            return [...m]
                        }
                      
                    }
                    
               
              })
            }
              
    }

    const  dealStr2Arr = (token:string)=>{
            // 正则表达式匹配
            const regex = /data: (\{(?:[^{}]|(?:\{[^{}]*\}))*\})/g;
            let match;
            const result = [];

            // 循环匹配字符串中的所有对象并存入数组
            while ((match = regex.exec(token)) !== null) {
                const jsonData = match[1];
                try {
                    const parsedData = JSON.parse(jsonData);
                    // 判断是否包含"value"和"path"字段
                    if (parsedData.ops && Array.isArray(parsedData.ops)) {
                    for (const op of parsedData.ops) {
                        if (op.op === "add" && op.path && op.value) {
                        result.push({ path: op.path, value: op.value });
                        }
                    }
                    }
                } catch (error) {
                    debugger;
                    console.error('解析 JSON 出错:', error);
                }
            }

            return result;

    }

    const adjustAspectRatio = ()=> {
        var aspectRatioBox = document.getElementById('digitalBoxId');
        var height = window.innerHeight;
        var width = height * (9 / 16);
        // @ts-ignore
        aspectRatioBox.style.width = width + 'px';
        setloadingFinish(true);
      }

    let currInput = ""

    useEffect(()=>{
        // adjustAspectRatio();
        // 在窗口大小调整时重新计算宽度
        // window.addEventListener('resize', adjustAspectRatio);
    })

    function isFullScreen() {
        return  !! (
            // @ts-ignore
            document.fullscreen || 
            // @ts-ignore
            document.mozFullScreen ||                         
            // @ts-ignore
            document.webkitIsFullScreen ||       
            // @ts-ignore
            document.webkitFullScreen || 
            // @ts-ignore
            document.msFullScreen 
         );
      }

    const [fullscreen, setfullscreen] = useRecoilState(fullscreenState)
    // 全屏
    const onFullScreen = ()=>{
        // 退出全屏
        if(isFullScreen()){
            setfullscreen(false)
            // @ts-ignore
            if (document.exitFullscreen) {
                // @ts-ignore
                document.exitFullscreen();
                // @ts-ignore
              } else if (document.mozCancelFullScreen) { // Firefox
                // @ts-ignore
                document.mozCancelFullScreen();
                // @ts-ignore
              } else if (document.webkitExitFullscreen) { // Chrome, Safari and Opera
                // @ts-ignore
                document.webkitExitFullscreen();
                // @ts-ignore
              } else if (document.msExitFullscreen) { // Internet Explorer and Edge
                // @ts-ignore
                document.msExitFullscreen();
              }
        // 全屏
        }else{
            setfullscreen(true)
            // const element = document.getElementById('digitalBoxId');
            const element = document.getElementById('digitalBoxId') as HTMLElement
            // @ts-ignore
            if (element.requestFullscreen) {
                 // @ts-ignore
            element.requestFullscreen();
             // @ts-ignore
            } else if (element.mozRequestFullScreen) { // Firefox
                 // @ts-ignore
            element.mozRequestFullScreen();
             // @ts-ignore
            } else if (element.webkitRequestFullscreen) { // Chrome, Safari and Opera
                 // @ts-ignore
            element.webkitRequestFullscreen();
             // @ts-ignore
            } else if (element.msRequestFullscreen) { // Internet Explorer and Edge
            // @ts-ignore
            element.msRequestFullscreen();
            }
        }
    }

    return (
        <Box id='digitalBoxId' sx={{margin:'0 auto',position:'relative',width:'1080px',height:'1920px',overflow:'hidden'}}>
        {/* <Box id='digitalBoxId' sx={{margin:'0 auto',position:'relative',width:'100vw',height:'100vh'}}> */}
        
             
              

                {/* <Box id='digitalBoxId' sx={{margin:'0 auto',position:'relative',height:'100vh',overflow:'hidden'}}> */}
                        <Box sx={{
                            width:'100%',height:'100%',
                            overflow: 'hidden',
                        }}>
                            {/* <Human></Human> */}
                            <iframe style={{
                                width: '100%',
                                height: '100%',
                                border:'none'
                            }} src={shuziren} allowFullScreen></iframe>
                            {/* <img src={DigitalBg} /> */}
                        </Box>
                        <Box sx={{
                            position: 'absolute',
                            top: '60%',
                            right: 0,
                            left:0,
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'center',
                            // minWidth: '700px',
                            // width: '100%',
                            height:'40%',
                            
                            // flex: 2,
                            zIndex: 99
                        }}>
                            <ChatBox></ChatBox>
                        </Box>
                        <Box sx={{
                            position: 'absolute',
                            bottom: '2px',
                            right: '50px',
                            cursor: 'pointer',
                            zIndex: 99
                        }}>
                            
                            
                            <img onClick={handleStopRendering}  src={pauseIcon}/>
                            
                        </Box>
                        <Box position="absolute" right="40px" top="40px" color="#FFF" zIndex={99} onTouchStart={onFullScreen} onClick={onFullScreen}>
                            <img src={fullscreenIcon} alt='widthFix'></img>
                        </Box>
                    </Box>

   
        

        
    );
}
